﻿using System;
using System.Data;
using System.Data.OleDb;
using System.Drawing.Printing;
using System.Reflection;
using C1.Win.C1Preview;
using C1.C1Report;
using PCSUtils.Framework.ReportFrame;
using PCSUtils.Utils;
using C1PrintPreviewDialog = PCSUtils.Framework.ReportFrame.C1PrintPreviewDialog;

namespace BaoCaoDuTru
{
	[Serializable]
	public class BaoCaoDuTru : MarshalByRefObject, IDynamicReport
	{
		public BaoCaoDuTru()
		{
		}

		private string mConnectionString;
		private ReportBuilder mReportBuilder;
		private C1PrintPreviewControl mReportViewer;
		private object mResult;

		/// <summary>
		/// ConnectionString, provide for the Dynamic Report
		/// ALlow Dynamic Report to access the DataBase of PCS
		/// </summary>
		public string PCSConnectionString
		{
			get { return mConnectionString; }
			set { mConnectionString = value; }
		}

		/// <summary>
		/// Report Builder Utility Object
		/// Dynamic Report can use this object to render, modify, layout the report
		/// </summary>
		public ReportBuilder PCSReportBuilder
		{
			get { return mReportBuilder; }
			set { mReportBuilder = value; }
		}

		/// <summary>
		/// ReportViewer Object, provide for the DynamicReport, 
		/// allow Dynamic Report to manipulate with the REportViewer, 
		/// modify the report after rendered if needed
		/// </summary>
		public C1PrintPreviewControl PCSReportViewer
		{
			get { return mReportViewer; }
			set { mReportViewer = value; }
		}

		/// <summary>
		/// Store other result if any. Ussually we store return DataTable here to display on the ReportViewer Form's Grid
		/// </summary>
		public object Result
		{
			get { return mResult; }
			set { mResult = value; }
		}

		private bool mUseReportViewerRenderEngine = false;

		/// <summary>
		/// Notify PCS whether the rendering report process is run by
		/// this IDynamicReport or the ReportViewer Engine (in the ReportViewer form)
		/// </summary>
		public bool UseReportViewerRenderEngine
		{
			get { return mUseReportViewerRenderEngine; }
			set { mUseReportViewerRenderEngine = value; }
		}

		private string mReportFolder = string.Empty;
		/// <summary>
		/// Inform External Process where to find out the ReportLayout	 ( the PCS' ReportDefinition Folder Path )
		/// </summary>				
		public string ReportDefinitionFolder
		{
			get { return mReportFolder; }
			set { mReportFolder = value; }
		}


		private string mLayoutFile = string.Empty;		
		/// <summary>
		/// Inform External Process about the Layout file
		/// in which PCS instruct to use
		/// (PCS will assign this property while ReportViewer Form execute,
		/// ReportVIewer form will use the layout file in the report config entry to put in this property)
		/// </summary>		
		public string ReportLayoutFile
		{
			get 
			{
				return mLayoutFile;
			}
			set
			{
				mLayoutFile = value;
			}
		}


		public object Invoke(string pstrMethod, object[] pobjParameters)
		{
			return this.GetType().InvokeMember(pstrMethod, BindingFlags.InvokeMethod, null, this, pobjParameters);
		}

		public DataTable ExecuteReport(string pstrFGoodsCode, string pstrProductionLineID, string pstrFullname)
		{
			DataTable dtbReportData = GetReportData(pstrFGoodsCode, pstrProductionLineID);

			#region report

			C1Report rptReport = new C1Report();
			
			if (mLayoutFile == string.Empty)
				mLayoutFile = "BaoCaoDuTru.xml";
			rptReport.Load(mReportFolder + "\\" + mLayoutFile, rptReport.GetReportInfo(mReportFolder + "\\" + mLayoutFile)[0]);
			rptReport.Layout.PaperSize = PaperKind.A4;
					
			#region report parameter
			string strLineCode = string.Empty;

			if (pstrProductionLineID != null && pstrProductionLineID.Length > 0)
				strLineCode = GetProductionLineInfo(pstrProductionLineID);
			try
			{
				rptReport.Fields["fldProductionLine"].Text = strLineCode;
			}
			catch{}
			try
			{
				rptReport.Fields["fldFullname"].Text = pstrFullname;
			}
			catch{}
				
			#endregion
				
			// set datasource object that provides data to report.
			rptReport.DataSource.Recordset = null;
			rptReport.DataSource.Recordset = dtbReportData;
			// render report
			rptReport.Render();

			// render the report into the PrintPreviewControl
			C1PrintPreviewDialog ppvViewer = new C1PrintPreviewDialog();
			ppvViewer.FormTitle = rptReport.Fields["fldTitle"].Text;
			ppvViewer.ReportViewer.NavigationPanelVisible = false;
			ppvViewer.ReportViewer.Document = rptReport.Document;
			ppvViewer.Show();
			#endregion

			return dtbReportData;
		}

		private DataTable GetReportData(string pstrFGOodsCode, string pstrProductionLineID)
		{
			OleDbConnection cn = null;
			try
			{
				cn = new OleDbConnection(mConnectionString);
				DataTable dtbItem = new DataTable();
				string strSql = "SELECT FGoodsCode, P.Code + ' (' + P.Description + ')' SPartNo, S.WOQuantity,"
					+ " i.Code PartNo,i.description PartName,Sum(WB.Quantity*WD.OrderQuantity) BomQty,UM.Code UM,"
					+ " Sum(WB.Quantity*WD.OrderQuantity*i.Rate) Weight, getdate() ServerDate"
					+ " from PRO_WOBom WB"
					+ " JOIN PRO_WorkOrderDetail WD ON WD.WorkOrderDetailID=WB.WorkOrderDetailID"
					+ " JOIN ITM_Product i on i.productID=WB.ComponentID"
					+ " JOIN MST_UnitOfMeasure UM ON UM.UnitOfMeasureID=WB.BomUMID"
					+ " JOIN SO_SaleOrderDetail S ON WD.SaleOrderDetailID = S.SaleOrderDetailID"
					+ " JOIN ITM_Product P ON S.ProductID = P.ProductID"
					+ " Where (ISNULL(i.makeitem,0)=0 OR i.Revision = 'CTTC')"
					+ " AND FGoodsCode = '" + pstrFGOodsCode + "'";
				if (pstrProductionLineID != null && pstrProductionLineID.Length > 0)
					strSql += " AND WD.ProductionLineID = " + pstrProductionLineID;
				strSql += " Group by FGoodsCode, P.Code, P.Description, S.WOQuantity, i.Code ,i.description ,UM.Code"
					+ " Order by FGoodsCode, P.Code, S.WOQuantity, i.Code ,i.description ,UM.Code";
				OleDbDataAdapter odad = new OleDbDataAdapter(strSql, cn);
				odad.Fill(dtbItem);
				return dtbItem;
			}
			finally
			{
				if (cn != null)
					if (cn.State != ConnectionState.Closed)
						cn.Close();
			}
		}

		private string GetProductionLineInfo(string pstrProductionLineID)
		{
			OleDbConnection cn = null;
			try
			{
				cn = new OleDbConnection(mConnectionString);
				string strSql = "SELECT Code + ' (' + Name + ')' FROM PRO_ProductionLine"
					+ " WHERE ProductionLineID = " + pstrProductionLineID;
				OleDbCommand ocmd = new OleDbCommand(strSql, cn);
				ocmd.Connection.Open();
				return ocmd.ExecuteScalar().ToString();
			}
			finally
			{
				if (cn != null)
					if (cn.State != ConnectionState.Closed)
						cn.Close();
			}
		}
	}
}